package com.unionServer.codecs;

import com.unionServer.models.GatewayMessage;
import com.unionServer.models.MessageBody;
import com.unionServer.models.MessageHead;
import com.unionServer.models.UnionDecodeMessage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @description:
 * @author: wangxinal
 * @time: 2022/1/8
 */
@Slf4j
public class UnionDecoder extends LengthFieldBasedFrameDecoder {

    private static final int HEADER_SIZE = 4;

    private int length;

    private String body;

    private byte[] byteBody;

    private UnionDecodeMessage unionDecodeMessage ;


    /**
     *
     * @param maxFrameLength 解码时，处理每个帧数据的最大长度
     * @param lengthFieldOffset 该帧数据中，存放该帧数据的长度的数据的起始位置
     * @param lengthFieldLength 记录该帧数据长度的字段本身的长度
     * @param lengthAdjustment 修改帧数据长度字段中定义的值，可以为负数
     * @param initialBytesToStrip 解析的时候需要跳过的字节数
     * @param failFast 为true，当frame长度超过maxFrameLength时立即报TooLongFrameException异常，为false，读取完整个帧再报异常
     */

    public UnionDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
        super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);

    }

    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, StandardCharsets.US_ASCII);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

        if (in == null) {
            return null;
        }

        if (in.readableBytes() < HEADER_SIZE) {
            throw new Exception("可读信息段比头部信息都小");
        }

        length = Integer.parseInt( hexStringToString( String.format("%08X",in.readInt()) ));

        log.info("长度应该是："+length);

        if (in.readableBytes() < length) {
            throw new Exception("body字段你告诉我长度是"+length+",但是真实情况是没有这么多");
        }

        ByteBuf buf = in.readBytes(length);

        byte[] req = new byte[buf.readableBytes()];

        buf.readBytes(req);

        body = new String(req,StandardCharsets.US_ASCII);

        if (length >0){
            unionDecodeMessage = new UnionDecodeMessage(req );
            MessageHead messageHead = unionDecodeMessage.getMessageHead();
            //messageHead.toString();
            MessageBody messageBody = unionDecodeMessage.getMessageBody();
            //messageBody.toString();
            log.info("拆包报文："+ Charset.defaultCharset());
        }

        byteBody = req;

        GatewayMessage gatewayMessage = new GatewayMessage( length,body,byteBody, String.valueOf(length));

        return gatewayMessage;

    }


}